#include "MutaAttractor.h"

// System includes
#include <cmath>
#include <stdlib.h>
#include <QGLFormat>
#include <QImage>
#include <QDebug>


QPainterPath MutaAttractor::path;
QPainter MutaAttractor::painter;
int MutaAttractor::frames = 200;
int MutaAttractor::iters = 200;
int MutaAttractor::skipIters = 0;
double MutaAttractor::sensitivity = 0.02;

void MutaAttractor::init()
{
    srand((unsigned) time(0));
    MutaAttractor::frames = 200;
    MutaAttractor::iters = 200;
    MutaAttractor::skipIters = 0;
    MutaAttractor::sensitivity = 0.02;
}

QPixmap MutaAttractor::renderAttractor(int w, int h)
{
    int width = w;
    int height = h;
    QPixmap map(width, height);
    map.fill(Qt::transparent);
    painter.begin(&map);
    painter.setRenderHints(QPainter::Antialiasing);

    QColor attractorColor = QColor(255,255,255,255);
    attractorColor.setAlpha(20);
    QPen attractorPen(attractorColor);
    attractorPen.setWidth(1);
    painter.setPen(attractorPen);
    painter.setBrush(attractorColor);

    double minX = -4.0;
    double minY = minX * height / width;

    double maxX = 4.0;
    double maxY = maxX * height / width;

    double minA = acos( (((float) rand() / (float) RAND_MAX) * 2) / 2.0 );
    double maxA = acos( (((float) rand() / (float) RAND_MAX) * 2) / 2.0 );

    double minB = acos( (((float) rand() / ((float) RAND_MAX) ) - 1) / 2.0 );
    double maxB = acos( (((float) rand() / ((float) RAND_MAX) ) - 1) / 2.0 );

    double minC = acos( (((float) rand() / ((float) RAND_MAX) ) - 1) / 2.0 );
    double maxC = acos( (((float) rand() / ((float) RAND_MAX) ) - 1) / 2.0 );

    double minD = acos( (((float) rand() / ((float) RAND_MAX) )) / 2.0 );
    double maxD = acos( (((float) rand() / ((float) RAND_MAX/2) )) / 2.0 );

    for(int i = 0; i < frames; i++)
    {
        const double p = static_cast<double>(i) / frames;
        const double a = cos(minA + p * (maxA - minA)) * 2.0;
        const double b = cos(minA + p * (maxB - minB)) * 2.0;
        const double c = cos(minC + p * (maxC - minC)) * 2.0;
        const double d = cos(minD + p * (maxD - minD)) * 2.0;

        double x = 0.0;
        double y = 0.0;

        for(int j = 0; j < iters; j++)
        {
            double xn = sin(a * y) + c * cos(a * x);
            double yn = sin(b * x) + d * cos(b * y);
            x = xn;
            y = yn;

            if(j < skipIters)
            {
                continue;
            }

            int xi = static_cast<int>((x - minX) * width / (maxX - minX));
            int yi = static_cast<int>((y - minY) * height / (maxY - minY));
            if(xi >= 0 && xi < width && yi >= 0 && yi < height )
            {
                painter.drawPoint(xi , yi);
            }
        }

    }
    painter.end();
    return map;
}

